package service

import (
	"context"
	"encoding/json"
	"log"
	"nearby/biz/common"
	"nearby/biz/dal/db/po"
	"nearby/biz/dal/db/repo"
	"nearby/biz/domain/entity"
)

type CommentService struct {
}

type ConstructCommentEntityRequest struct {
	UserID     int64                 `json:"user_id"`     // (创建者)用户id
	EntityID   int64                 `json:"entity_id"`   // 被评论的实体id
	EntityType string                `json:"entity_type"` // 被评论的实体类型, 枚举值, "评论": comment; "动态": moment
	Content    entity.CommentContent `json:"content"`     // 评论内容
}

func (ss *CommentService) ConstructCommentEntity(ctx context.Context, req ConstructCommentEntityRequest) (*entity.Comment, error) {
	commentEntity := &entity.Comment{
		User: entity.User{
			UserID: req.UserID,
		},
		EntityID:   req.EntityID,
		EntityType: req.EntityType,
		Content:    req.Content,
	}
	commentEntity.SetCommentID()
	return commentEntity, nil
}

type GetCommentsRequest struct {
	MomentID int64 `json:"moment_id"`
	Limit    int64 `json:"limit"`
	Offset   int64 `json:"offset"`
}

func (ss *CommentService) GetComments(ctx context.Context, req GetCommentsRequest) (commentEntities []*entity.Comment, total int64, err error) {
	commentRepo := repo.NewCommentRepo(ctx)
	repoReq := ss.ToRepoReq(ctx, req)
	commentPos, total, err := commentRepo.GetComments(ctx, repoReq)
	if err != nil {
		return nil, 0, err
	}
	commentEntities, _ = ss.ToCommentEntities(commentPos)
	return commentEntities, total, nil
}

func (ss *CommentService) ToCommentEntities(pos []*po.Comment) ([]*entity.Comment, error) {
	commentEntities := make([]*entity.Comment, 0)
	for i := range pos {
		commentEntity, err := ss.ToCommentEntity(pos[i])
		if err != nil {
			log.Printf("ss.ToCommentEntity fail, err: %+v", err)
		}
		commentEntities = append(commentEntities, commentEntity)
	}
	return commentEntities, nil
}

func (ss *CommentService) ToRepoReq(ctx context.Context, req GetCommentsRequest) repo.GetCommentsRequest {
	repoReq := repo.GetCommentsRequest{
		Limit:  req.Limit,
		Offset: req.Offset,
	}
	if req.MomentID != 0 {
		repoReq.EntityType = common.EntityTypeMoment
		repoReq.EntityID = req.MomentID
	}
	return repoReq
}

func (ss *CommentService) ToCommentEntity(c *po.Comment) (*entity.Comment, error) {
	commentEntity := &entity.Comment{
		CommentID: c.CommentID,
		User: entity.User{
			UserID: c.UserID,
		},
		EntityID:     c.EntityID,
		EntityType:   c.EntityType,
		LikeCount:    c.LikeCount,
		CommentCount: c.CommentCount,
		CreateAt:     c.CreatedAt,
	}
	err := json.Unmarshal(c.Content, &commentEntity.Content)
	if err != nil {
		return nil, err
	}
	return commentEntity, nil
}
